/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2011, Salzburg Research. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of the LMF library client Project nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributor(s):
 * Stephanie Stroka
 *
 * File Info:
 * User: Stephanie Stroka
 * Date: 2011/08/19
 * Time: 18:04
 *
 * Project: lmflib
 */

package kiwi.facading.model.resources;

import java.util.Locale;

/**
 * Created by IntelliJ IDEA.
 * User: sstroka
 * Date: 31.05.2011
 * Time: 12:55:21
 * To change this template use File | Settings | File Templates.
 */
public abstract class KiWiLiteral extends KiWiNode {

    public static final String NS_XSD          = "http://www.w3.org/2001/XMLSchema#";

    private String contentMd5;

    private Locale language;

    private String type;

    public KiWiLiteral() {
        super();
    }

    protected KiWiLiteral(Locale language, String type) {
        this();
        this.language = language;
        this.type = type;
    }

    public KiWiLiteral(String content, Locale language, String type) {
        this(language,type);
        setContent(content);
     }


    public KiWiLiteral(KiWiResource creator) {
        super(creator);
    }

     /**
     * Return the content of the literal, using the parametrized Java type
     * @return
     */
    public abstract String getContent();


    /**
     * Set the content of the literal to the content provided as parameter.
     * @param content
     */
    public abstract void setContent(String content);

    /**
     * Get the locale representing the language this literal is in; returns null
     * if no language is associated with the literal
     * @return
     */
    public Locale getLanguage() {
        return language;
    }

    /**
     * Set the language of this literal to the given locale.
     * @param language
     */
    public void setLanguage(Locale language) {
        this.language = language;
    }

    /**
     * Return the RDF/XSD type of this literal.
     * @return
     */
    public String getType() {
        return type;
    }

    /**
     * Set the RDF/XSD type of this literal.
     * @param type
     */
    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("\""+getContent()+"\"");
        if(language != null) {
            result.append("@"+language.getLanguage());
        }
        if(type != null) {
			result.append("^^"+getType().toString());
		}
        return result.toString();
    }

    /**
     * A separate equalsContent method for checking whether literals are equal in their content; we cannot override
     * the .equals function with this because it would break the system in cases where the same content is used in
     * different literals.
     *
     * @param o
     * @return
     */
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || o.getClass() != this.getClass()) {
            return false;
        }


        KiWiLiteral that = (KiWiLiteral) o;

        if (getContentMd5() != null ? !getContentMd5().equals(that.getContentMd5()) : that.getContentMd5() != null) return false;
        if (getLanguage() != null ? !getLanguage().equals(that.getLanguage()) : that.getLanguage() != null) return false;
        if (getType() != null ? !getType().equals(that.getType()) : that.getType() != null) return false;

        return true;
    }


    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + (this.getContentMd5() != null ? this.getContentMd5().hashCode() : 0);
        hash = 89 * hash + (this.getLanguage() != null ? this.getLanguage().hashCode() : 0);
        hash = 89 * hash + (this.getType() != null ? this.getType().hashCode() : 0);
        return hash;
    }

	/**
	 * @author
	 * @return
	 * @see KiWiNode#getCacheKey()
	 */
	@Override
	public String getCacheKey() {
        //return TripleStoreUtil.createLiteralCacheKey(contentMd5,language,type);
        return contentMd5 +  ( language==null?"":("@" + language.toString()) ) + ( type==null?"":("^^" + type.toString()) );
	}



	@Override
	public boolean isAnonymousResource() {
		return false;
	}

	@Override
	public boolean isLiteral() {
		return true;
	}

	@Override
	public boolean isUriResource() {
		return false;
	}

	@Override
	public String getShortName() {
		return getContentMd5();
	}

	public String getContentMd5() {
		return contentMd5;
	}

	public void setContentMd5(String contentMd5) {
		this.contentMd5 = contentMd5;
	}

    /**
     * Return a representation of the node in TURTLE syntax.
     * <p/>
     * http://www.w3.org/TeamSubmission/turtle/
     *
     * @return
     */
    @Override
    public String toTurtle() {
        String s_lang = language != null ? "@" + language.getLanguage() : "";
        String s_type = type != null && !type.equals(NS_XSD+"string") ?
                        "^^<" + type +">" : "";

        String content = getContent();
        String s_content;

        if(content.contains("\n")) {
            s_content = "\"\"\"" + content + "\"\"\"";
        } else {
            s_content = "\"" + content + "\"";
        }

        return s_content + s_lang + s_type;
    }


    /**
     * Return a representation of the node in RDF/JSON syntax.
     * <p/>
     * http://n2.talis.com/wiki/RDF_JSON_Specification
     *
     * @param asObject indicates whether formatting should be as object (i.e. with additional type information)
     * @return
     */
    @Override
    public String toJSON(boolean asObject) {
        if(!asObject) {
            throw new IllegalArgumentException("literals can only be formatted as objects");
        }

        return "{ \"type\" : \"literal\"," +
                " \"value\" : \"" + getContent().replace("\"","\\\"") + "\"" +
                (language != null ? ", \"lang\" : \""+language.getLanguage() + "\"" : "") +
                (type != null && !type.equals(NS_XSD+"string") ?
                                    ", \"type\" : \""+type+"\"" : "") +
                " }";

    }
}
